package org.xwalk.core.internal;

import android.net.Uri;
import java.util.Map;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class XWalkWebResourceRequestHandlerBridge extends XWalkWebResourceRequestHandlerInternal {
    private XWalkCoreBridge coreBridge;
    private Object wrapper;

    public Object getWrapper() {
        return wrapper;
    }


    private XWalkWebResourceRequestHandlerInternal internal;

    XWalkWebResourceRequestHandlerBridge(XWalkWebResourceRequestHandlerInternal internal) {
        this.internal = internal;
        reflectionInit();
    }

    @Override
    public Uri getUrl() {
        if (getUrlMethod == null || getUrlMethod.isNull()) {
            return getUrlSuper();
        } else {
            return (Uri)getUrlMethod.invoke();
        }
    }

    public Uri getUrlSuper() {
        Uri ret;
        if (internal == null) {
            ret = super.getUrl();
        } else {
            ret = internal.getUrl();
        }
        if (ret == null) return null;
        return ret;
    }

    private ReflectMethod getUrlMethod = new ReflectMethod(null, "getUrl");

    @Override
    public boolean isForMainFrame() {
        if (isForMainFrameMethod == null || isForMainFrameMethod.isNull()) {
            return isForMainFrameSuper();
        } else {
            return (Boolean)isForMainFrameMethod.invoke();
        }
    }

    public boolean isForMainFrameSuper() {
        boolean ret;
        if (internal == null) {
            ret = super.isForMainFrame();
        } else {
            ret = internal.isForMainFrame();
        }
        
        return ret;
    }

    private ReflectMethod isForMainFrameMethod = new ReflectMethod(null, "isForMainFrame");

    @Override
    public boolean hasGesture() {
        if (hasGestureMethod == null || hasGestureMethod.isNull()) {
            return hasGestureSuper();
        } else {
            return (Boolean)hasGestureMethod.invoke();
        }
    }

    public boolean hasGestureSuper() {
        boolean ret;
        if (internal == null) {
            ret = super.hasGesture();
        } else {
            ret = internal.hasGesture();
        }
        
        return ret;
    }

    private ReflectMethod hasGestureMethod = new ReflectMethod(null, "hasGesture");

    @Override
    public String getMethod() {
        if (getMethodMethod == null || getMethodMethod.isNull()) {
            return getMethodSuper();
        } else {
            return (String)getMethodMethod.invoke();
        }
    }

    public String getMethodSuper() {
        String ret;
        if (internal == null) {
            ret = super.getMethod();
        } else {
            ret = internal.getMethod();
        }
        if (ret == null) return null;
        return ret;
    }

    private ReflectMethod getMethodMethod = new ReflectMethod(null, "getMethod");

    @Override
    public Map<String, String> getRequestHeaders() {
        if (getRequestHeadersMethod == null || getRequestHeadersMethod.isNull()) {
            return getRequestHeadersSuper();
        } else {
            return (Map<String, String>)getRequestHeadersMethod.invoke();
        }
    }

    public Map<String, String> getRequestHeadersSuper() {
        Map<String, String> ret;
        if (internal == null) {
            ret = super.getRequestHeaders();
        } else {
            ret = internal.getRequestHeaders();
        }
        if (ret == null) return null;
        return ret;
    }

    private ReflectMethod getRequestHeadersMethod = new ReflectMethod(null, "getRequestHeaders");


    void reflectionInit() {
        coreBridge = XWalkCoreBridge.getInstance();
        if (coreBridge == null) return;

        ReflectConstructor constructor = new ReflectConstructor(
                coreBridge.getWrapperClass("XWalkWebResourceRequestHandler"), Object.class);
        try {
            wrapper = constructor.newInstance(this);
        } catch (UnsupportedOperationException e) {
            return;
        }

        getUrlMethod.init(wrapper, null,
                "getUrl");
        isForMainFrameMethod.init(wrapper, null,
                "isForMainFrame");
        hasGestureMethod.init(wrapper, null,
                "hasGesture");
        getMethodMethod.init(wrapper, null,
                "getMethod");
        getRequestHeadersMethod.init(wrapper, null,
                "getRequestHeaders");
    }
}
